package chapter1.zyq1_str_obj;

import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;

public class sendReceiveUtil_Str23 {
    public static String recvString(Socket socket) throws Exception{
        byte[] ibytes = recv(socket);
        String msg = new String(ibytes,0, ibytes.length,"utf-8");
        return msg;
    }

    //接收包含字节个数的一组字节。
    private static byte[] recv(Socket socket) throws Exception{
        byte[] countBytes = new byte[4];
        readFully(socket, countBytes);
        int count = byteArrayToInt(countBytes);
        byte[] dataBytes = new byte[count];
        readFully(socket, dataBytes);
        return dataBytes;
    }

    //从socket接收字节，把数组bytes填满
    private static void readFully(Socket socket, byte[] bytes) throws Exception{
        InputStream ins = socket.getInputStream();
        int bytesToRead = bytes.length;
        int readCount = 0;
        while (readCount < bytesToRead) {
            int result = ins.read(bytes, readCount, bytesToRead - readCount);
            // Stream意外结束
            if (result == -1) {
                throw new Exception("异常：InputStream意外结束!");
            }
            readCount += result;
        }
    }

    //把字节数组转成对应的整数
    public static int byteArrayToInt(byte[] b) {
        return b[3] & 0xFF |
                (b[2] & 0xFF) << 8 |
                (b[1] & 0xFF) << 16 |
                (b[0] & 0xFF) << 24;
    }


    //发送一个字符串
    public static void sendString(Socket socket, String msg) throws Exception{
        byte[] obytes = msg.getBytes("utf-8");
        send(socket, obytes);
    }

    //发送包含字节个数的一组字节。
    private static void send(Socket socket, byte[] obytes) throws Exception{
        OutputStream outs = socket.getOutputStream();
        int bytesCount = obytes.length;
        //先发送字节数
        byte[] cntBytes = intToByteArray(bytesCount);
        outs.write(cntBytes, 0, cntBytes.length);
        outs.flush();
        outs.write(obytes, 0, obytes.length);
        outs.flush();
    }

    //把整数转成对应的字节数组
    public static byte[] intToByteArray(int a) {
        return new byte[] {
                (byte) ((a >> 24) & 0xFF),
                (byte) ((a >> 16) & 0xFF),
                (byte) ((a >> 8) & 0xFF),
                (byte) (a & 0xFF)
        };
    }

}
